#include "listnode.h"
#include <stdio.h>
#include <stdlib.h>
Node * Node_construct(int v)
{
  Node * n = malloc(sizeof(Node));
  n -> ln_value = v;
  n -> ln_next = 0;
  return n;
}

Node * List_insert(Node * n, int v)
{
  /* insert at the beginning */
  Node * p = Node_construct(v);
  /* comment */
  p -> ln_next = n; 
  return p;
}

Node * List_copy(Node * n2)
{
  Node * next = n2;
  Node * n;
  if (n2 == 0) { return 0; }
  n = Node_construct(n2 -> ln_value);
  next = next -> ln_next;
  while (next != 0)
    {
      n = List_insert(n, next -> ln_value);
      next = next -> ln_next;
    }
  return n;
}

void List_assign(Node * * n1, Node * n2)
{
  if ((* n1) == n2)
    { return; }
  List_destruct(* n1);
  * n1 = List_copy(n2);   
}

void Node_destruct(Node * n)
{
  free (n);
}

void List_destruct(Node * n)
{
  Node * prev = n;
  Node * next;
  while (prev != 0)
    {
      next = prev -> ln_next;
      Node_destruct(prev);
      prev = next;
    }
}

int Node_getValue(Node * n)
{
  return (n -> ln_value);
}

void Node_print(Node * n)
{
  printf("%d ", n -> ln_value);
}

void List_print(Node * n)
{
  Node * curr = n;
  while (curr != 0)
    {
      Node_print(curr);
      curr = curr -> ln_next;
    }
  printf("\n\n");
}
int List_search(Node * list, int v, Node * * n)
{
  /* is v inside the list? If not, return 0. */
  /* If so, return 1 and n points to the node. */
  /* Node n points to part of list, not a separate list.  Therefore,
     we should not intend to delete the list starting at n */
  Node * curr = list;
  (* n) = 0;
  while ((curr != 0) && ((curr -> ln_value != v)))
    /* must check curr first */
    {
      curr = curr -> ln_next;
    } 
  if (curr == 0) /* cannot find it */
    {
      return 0;
    }
  (* n) = curr;
  return 1;
}

int List_delete(Node * * list, int v)
{
  /* return 1 if found and delete */
  /* return 0 if not found */
  Node * curr = (* list);
  Node * prev = (* list);
  while ((curr != 0) && ((curr -> ln_value != v)))
    {
      prev = curr;
      curr = curr -> ln_next;
    }
  if (curr == 0) /* not found */
    {
      return 0;
    }
  if (curr == (* list)) /* first node */
    {
      (* list) = (* list) -> ln_next;
    }
  else
    {
      prev -> ln_next = curr -> ln_next;
    }
  Node_destruct(curr);
  return 1; 
}
